home *** CD-ROM | disk | FTP | other *** search
- import java.util.*;
- import java.io.*;
-
- public class Cgi extends Object
- {
-
- public static boolean needsEncode(char x)
- {
- return !(Character.isDigit(x)||Character.isUpperCase(x)
- ||Character.isLowerCase(x)||(x==' '));
- }
-
- public static String decodeCGIData(String queryString)
- {
- StringBuffer tmp = new StringBuffer(queryString);
- decodeData(tmp);
- return tmp.toString();
- }
-
- public static void decodeData(StringBuffer queryString)
- {
- /* Temporary variables */
- int i = 0, j = 0, max = 0;
- char c;
-
- /*
- * Loop over the string.
- * We use two loop indices,
- * i is the actual current character
- * j is used to move ahead when hex codes are found
- * Two indices are needed since the string shrinks
- * as hex-codes are turned into single characters.
- */
- if(queryString != null) max = queryString.length();
-
- for (i=0, j=0; j < max; ++i, ++j)
- {
- /* If we have found hex-codes, j>i so copy the data down. */
-
- queryString.setCharAt(i,queryString.charAt(j));
-
- if ('+' == queryString.charAt(i)) /* Convert pluses to spaces */
- {
- queryString.setCharAt(i,' ');
- }
- else if ('%' == queryString.charAt(j))/* Convert hex codes */
- {
- /*
- * Get the first number of the hex code, and store it
- * as a char.
- */
-
- c = (char)(((queryString.charAt(j+1) >= 'A') ?
- ((queryString.charAt(j+1) & 0xdf) - 'A') + 10
- : (queryString.charAt(j+1) - '0')));
- /*
- * The first hex-code was the 16 places, so multiply
- * c by 16.
- */
-
- c *= 16;
-
- /*
- * Get the second number in the hex code and add that
- * to the value of c.
- * c now stores the correct character for the hex code.
- */
- c += (char)(((queryString.charAt(j+2) >= 'A') ?
- ((queryString.charAt(j+2) & 0xdf) - 'A') + 10
- : (queryString.charAt(j+2) - '0')));
-
- /* Replace the % char we copied with the actual character. */
- queryString.setCharAt(i,c);
-
- /* Move j past the hex-code */
- j += 2;
- }
- }
-
- /* Truncate the string to remove trailing characters */
- queryString.setLength(i);
- }
-
- public static String encodeCGIData(String aString)
- {
- StringBuffer tmp = new StringBuffer(aString);
- encodeData(tmp);
- return tmp.toString();
- }
-
- /* encodeData() encodes a string for CGI */
- public static void encodeData(StringBuffer aString)
- {
- int i,size,l,push = 0;
-
- if(aString.length() != 0)
- {
-
- /* figure out the size after encoding */
- l=aString.length();
-
- for(i=0;i<l;i++)
- {
- if(Cgi.needsEncode(aString.charAt(i)))
- {
- push+=2;
- }
- }
-
- /* If we encountered characters to encode, encode them */
- if(push != 0)
- {
- /* Grow as needed */
- aString.setLength(l+push);
-
- /* Start encoded, back to front to reduce copying */
- for(i=l-1;i>=0;i--)
- {
- if(Cgi.needsEncode(aString.charAt(i)))
- {
- int tmp;
-
- tmp = (aString.charAt(i))%16;
- aString.setCharAt(i+push,(char)((tmp>=10)? (tmp-10 + 'A') : (tmp+'0')));
- push--;
-
- tmp = (aString.charAt(i))/16;
- aString.setCharAt(i+push,(char)((tmp>=10)? (tmp-10 + 'A') : (tmp+'0')));
-
- push--;
- aString.setCharAt(i+push,'%');
- }
- else/*push the other char back*/
- {
- aString.setCharAt(i+push,aString.charAt(i));
- }
- }
- }
-
- l=aString.length();
- /*Convert the spaces to pluses */
- for(i=0;i<l;i++)
- {
- if(aString.charAt(i) == ' ') aString.setCharAt(i,'+');
- }
-
- }
- }
-
- /*
- * encodeDictionary() encodes a dictionary in the form
- * of CGI data.
- */
- public static String encodeDictionary(Hashtable dataDict)
- {
- StringBuffer returnString;
- Enumeration state;
- String key;
- Object value;
- StringBuffer buffer;
- boolean needAmp = false;
-
- /* allocate the string */
- returnString =new StringBuffer();
- buffer =new StringBuffer();
-
- /* Create a dictionary state */
- state = dataDict.keys();
-
- /* Calculate how long the string will be */
-
- while(state.hasMoreElements())
- {
- key = (String) state.nextElement();
-
- /* If this isn't a multiple value, encode and append it */
- if((key.length()!=0) && (key.charAt(0) != 'A')
- && (key.charAt(1)!='_'))
- {
- value = dataDict.get(key);
-
- buffer.setLength(0);
- buffer.append(key);
- encodeData(buffer);
-
- if(needAmp)
- {
- returnString.append('&');
- }
-
- returnString.append(buffer);
- returnString.append('=');
-
- if(value!=null)
- {
- buffer.setLength(0);
- buffer.append((String)value);
- encodeData(buffer);
- }
- else
- {
- buffer.setLength(0);
- }
-
- returnString.append(buffer);
-
- needAmp = true;
- }
- }
-
- return returnString.toString();
- }
-
- public static Hashtable parseData(String queryString)
- {
- /* Temporary variables */
- StringTokenizer cursor;
- String key,value;
- Hashtable dataDict = new Hashtable();
-
- cursor = new StringTokenizer(queryString,"&=",true);
-
- while(cursor.hasMoreElements())
- {
-
- key = null;/* Reset the tmp key */
-
- value = null;/* Reset the tmp value */
-
- key = cursor.nextToken();
-
- /* If we have a key, try to read the value */
-
- if( key != null)
- {
-
- /*
- * See if the next character is a &,
- * if it is the key has an empty value.
- */
-
- if(cursor.hasMoreElements()&&
- (cursor.nextToken().equals("=")))
- {
- value = cursor.nextToken();
- if(cursor.hasMoreElements())
- cursor.nextToken();//Get rid of seperator
-
- /*
- * Decode the key and value
- */
-
- key = decodeCGIData(key);
- value = decodeCGIData(value);
- }
- else/* Key has an empty value */
- {
- /*
- * Decode the key, then
- * print the key and an empty value
- */
- if(cursor.hasMoreElements())
- cursor.nextToken();//Get rid of seperator
-
- key = decodeCGIData(key);
-
- value = new String("");
- }
-
- /*
- * Insert the value into the dictionary, but
- * allow for multiple values on key.
- * Put multiple values into an Array, with the key,
- * A_key.
- */
-
- /* Check if this is a multiple value */
- if((dataDict.get(key)) != null)
- {
- /* Create the name for the array key */
- String aName;
-
- aName = "A_"+key;
-
- /* Check if the array is in the dict, already */
-
- if((dataDict.get(aName))!=null)
- {
- /* Add the new value to the array */
- Vector theArray;
-
- theArray = (Vector) dataDict.get(aName);
-
- theArray.addElement(value);
-
- /* Set the dictionaries value, to the latest */
-
- dataDict.put(key, value);
- }
- else /* If not, ... */
- {
- /* Create the array */
- Vector theArray = null;
- theArray = new Vector();
-
- /* Add the first value to the array */
- theArray.addElement(dataDict.get(key));
-
- /* Add the new value to the array */
- theArray.addElement(value);
-
- /* Set the dictionaries value, to the latest */
- dataDict.put(key, value);
-
- /* Add the array to the dictionary */
- dataDict.put(aName,theArray);
- }
- }
- else /* If not, simple insert the value */
- {
- dataDict.put(key, value);
- }
-
- }
-
- }
-
- return dataDict;
- }
-
- public static String readGetData()
- {
- String queryString;
- queryString = System.getProperty("QUERY_STRING");
-
- if(queryString == null)
- {
- queryString = new String("");
- }
-
- return queryString;
- }
-
- public static String readPostData()
- {
- /* The data after it is read in */
- String queryString;
-
- /* The amount of data to read */
- int contentLength,i;
-
- /* Temporary variables for storing envvar and reading*/
- String sizeString;
- byte data[] = null;
-
- /* Read the environment variable CONTENT_LENGTH */
-
- sizeString = System.getProperty("CONTENT_LENGTH");
-
-
- /* If the env. var. existed, convert the string to an integer */
-
- if (sizeString!=null)
- {
- contentLength = Integer.parseInt( sizeString );
- data = new byte[contentLength];
- }
- else
- {
- contentLength = 0;
- }
-
- if ( data != null)
- {
- i = 0;
-
- try
- {
- while( i < contentLength)
- {
- data[ i++ ] = (byte) System.in.read();
- }
- }
- catch(IOException exp)
- {
- data = null;
- }
- /* Set the arguement to point to the data. */
-
- if(data != null) queryString = new String(data,0);
- else queryString = new String("");
-
- }
- else
- {
- queryString = new String("");
- }
-
- return queryString;
- }
-
- public static String readData()
- {
- String requestType = null;
- String retVal = null;
-
-
- /* Read the request type */
-
- requestType = System.getProperty("REQUEST_METHOD");
-
- /*
- * If it is a GET request use readGetData,
- * otherwise, if it is a POST request, use readPostData.
- */
-
- if((requestType != null) && requestType.equals("GET"))
- {
- retVal = readGetData();
- }
- else if((requestType != null) && requestType.equals("POST"))
- {
- retVal = readPostData();
- }
- else
- {
- retVal = new String("");
- }
-
- return retVal;
- }
-
- public static Hashtable readParse()
- {
- Hashtable returnData = null;
- String data;
-
- data = readData();
-
- if(data!=null) returnData = parseData(data);
-
- return returnData;
- }
-
- public static void main(String argv[])
- {
- FileInputStream raw;
- DataInputStream input;
- String key,value;
- String curLine;
- Hashtable data,decodedData;
- String encodedData;
- Enumeration cursor;
- int matches,total,ind;
-
- if(argv.length > 0)
- {
- try
- {
- raw = new FileInputStream(argv[0]);
- input = new DataInputStream(raw);
- data = new Hashtable();
-
- while(input.available() != 0)
- {
- curLine = input.readLine();
- ind = curLine.indexOf(' ');
-
- key = curLine.substring(0,ind);
- value = curLine.substring(ind+1);
- data.put(key,value);
- }
-
- encodedData = encodeDictionary(data);
- decodedData = parseData(encodedData);
-
- cursor = data.keys();
- matches = 0;
- total = 0;
-
- while(cursor.hasMoreElements())
- {
- key = (String)cursor.nextElement();
- value = (String)decodedData.get(key);
-
- if(data.get(key).equals(value))
- {
- matches++;
- System.out.println(data.get(key) + " = " + value);
- }
- else
- {
- System.out.println(data.get(key) + " != " + value);
- }
- total++;
- }
-
- if(matches == total)
- {
- System.out.println("Test succeeded.");
- }
- else
- {
- System.out.println("Test failed.");
- }
-
-
- input.close();
- raw.close();
- }
- catch(IOException exp)
- {
- System.out.println("Encountered IO exception!");
- }
- }
- else
- {
- System.out.println("usage: java Cgi filename");
- System.out.println("The file should have space seperated keys and values\n");
- }
- }
-
- }
-